package initialize

import (
	"github.com/fsnotify/fsnotify"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/config_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"gopkg.in/yaml.v3"
	"path"
	"portal_api/config"
	"portal_api/global"
)

func IsDebug(mode string) bool {
	return mode == "dev" || mode == "local" || mode == "test"
}

var configClient config_client.IConfigClient

func InitConfig(mode string) {
	// 初始化配置文件
	v := viper.New()
	v.SetConfigFile(path.Join("etc", "portal", "portal-"+mode+".yaml"))
	if err := v.ReadInConfig(); err != nil {
		zap.L().Panic("读取配置失败", zap.Error(err))
	}
	global.NacosConfig = new(config.NacosConfig)
	if err := v.Unmarshal(global.NacosConfig); err != nil {
		zap.L().Panic("解析配置失败", zap.Error(err))
	}
	zap.L().Info("nacos config:", zap.Any("config", global.NacosConfig))

	v.WatchConfig()
	v.OnConfigChange(func(in fsnotify.Event) {
		zap.L().Info("配置文件修改了...")
		if err := v.Unmarshal(global.NacosConfig); err != nil {
			zap.L().Panic("解析配置失败", zap.Error(err))
			return
		}

		if configClient != nil {
			err := configClient.CancelListenConfig(vo.ConfigParam{
				DataId: global.NacosConfig.DataID,
				Group:  global.NacosConfig.Group,
			})
			if err != nil {
				zap.L().Error("取消监听失败", zap.Error(err))
				return
			}
		}

		initServerConfig(IsDebug(mode))
		zap.L().Info("nacos config:", zap.Any("config", global.NacosConfig))
	})

	initServerConfig(IsDebug(mode))
}

func initServerConfig(isDebug bool) {

	var err error

	sc := []constant.ServerConfig{
		{
			IpAddr: global.NacosConfig.Host,
			Port:   global.NacosConfig.Port,
		},
	}

	cc := constant.ClientConfig{
		NamespaceId:         global.NacosConfig.NamespaceId,
		TimeoutMs:           global.NacosConfig.TimeoutMs,
		NotLoadCacheAtStart: true,
		LogDir:              global.NacosConfig.LogDir,
		CacheDir:            global.NacosConfig.CacheDir,
		LogRollingConfig: &constant.ClientLogRollingConfig{
			MaxSize:    global.NacosConfig.MaxSize, // megabytes
			MaxBackups: global.NacosConfig.MaxBackups,
			MaxAge:     global.NacosConfig.MaxAge, // days
		},
		LogLevel:    global.NacosConfig.LogLevel, // debug,info,warn,error,
		AppName:     global.NacosConfig.AppName,
		ContextPath: global.NacosConfig.ContextPath,
		Username:    global.NacosConfig.Username,
		Password:    global.NacosConfig.Password,
	}

	configClient, err = clients.CreateConfigClient(map[string]interface{}{
		"serverConfigs": sc,
		"clientConfig":  cc,
	})

	if err != nil {
		zap.L().Panic("初始化nacos配置失败", zap.Error(err))
		return
	}

	content, err := configClient.GetConfig(vo.ConfigParam{
		DataId: global.NacosConfig.DataID,
		Group:  global.NacosConfig.Group,
	})
	if err != nil {
		zap.L().Panic("获取配置失败", zap.Error(err))
		return
	}
	global.ServerConfig = new(config.PortalApiConfig)
	err = yaml.Unmarshal([]byte(content), global.ServerConfig)
	if err != nil {
		zap.L().Panic("解析配置失败", zap.Error(err))
		return
	}
	err = configClient.ListenConfig(vo.ConfigParam{
		DataId: global.NacosConfig.DataID,
		Group:  global.NacosConfig.Group,
		OnChange: func(_, _, _, data string) {
			zap.L().Info("配置中心文件修改了...")
			err = yaml.Unmarshal([]byte(data), global.ServerConfig)
			if err != nil {
				zap.L().Panic("解析配置失败", zap.Error(err))
				return
			}
			zap.L().Info("server config:", zap.Any("config", global.ServerConfig))
		},
	})
	if err != nil {
		zap.L().Panic("监听配置失败", zap.Error(err))
		return
	}
}
